package com.android.gpuimage;

import android.graphics.PointF;
import android.opengl.GLES20;

import com.android.gpuimage.util.FilterTools;

/**
 * Created by winn on 17/8/14.
 */

public class EnLargerFilter extends GPUImageFilter {

    /*public static final String ENLARGER_FILTER_FRAGMENT_SHADER = "" +
            "varying highp vec2 textureCoordinate;\n" +
            "uniform sampler2D inputImageTexture;\n" +
            "uniform highp float aspectRatio;\n" +
            "uniform highp vec2 center;\n" +
            "uniform highp float radius;\n" +
            "uniform highp float scale;\n" +
            "void main() {\n" +
            "  highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n" +
            "  highp float dist = distance(center, textureCoordinateToUse);\n" +
            "  textureCoordinateToUse = textureCoordinate;\n" +
            "  if (dist < radius){\n" +
            "    textureCoordinateToUse -= center;\n" +
            "    highp float percent = 1.0 - ((radius - dist) / radius) * scale;\n" +
            "    percent = percent * percent;\n" +
            "    textureCoordinateToUse = textureCoordinateToUse * percent;\n" +
            "    textureCoordinateToUse += center;\n" +
            "  }\n" +
            "  gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse);\n" +
            "}";
    */

    public static final String ENLARGER_FILTER_FRAGMENT_SHADER = "" +
            "varying highp vec2 textureCoordinate;\n" +
            "uniform sampler2D inputImageTexture;\n" +
            "uniform highp float aspectRatio;\n" +
            "uniform highp vec2 center;\n" +
            "uniform highp float radius;\n" +
            "uniform highp float scale;\n" +
            "\n" +
            "void main() {\n" +
            "    highp float R = 0.3;\n" +
            "    highp float h = 0.1;\n" +
            "    highp float hr = R * sqrt(1.0 - ((R - h) / R) * ((R - h) / R));\n" +
            "\n" +
            "    highp vec2 xy = textureCoordinate.xy - center.xy;\n" +
            "    highp float r = sqrt(xy.x * xy.x + xy.y * xy.y);\n" +
            "    highp vec2 new_xy = r < hr ? xy * (R - h) / sqrt(R * R - r * r) : xy;\n" +
            "\n" +
            "    gl_FragColor = texture2D(inputImageTexture, (new_xy + center.xy));\n" +
            "}";



//    public static final String ENLARGER_FILTER_FRAGMENT_SHADER = "" +
//            "fGt4c2NkbSpiY21ieip8b2k4Kn5vcn5/eG9JZWV4bmNka35vMQB/ZGNsZXhnKnlrZ3pmb3g4TipjZHp/fkNna21vXm9yfn94bzEAf2RjbGV4ZypiY21ieipsZmVrfipreXpvaX5Ya35jZTEAf2RjbGV4ZypiY21ieip8b2k4KmlvZH5veDEAf2RjbGV4ZypiY21ieipsZmVrfip4a25jf3kxAH9kY2xleGcqYmNtYnoqbGZla34qeWlrZm8xAHxlY24qZ2tjZCIjKnEAKipiY21ieip8b2k4Kn5vcn5/eG9JZWV4bmNka35vXmVfeW8qNyp8b2k4In5vcn5/eG9JZWV4bmNka35vJHImKiJ+b3J+f3hvSWVleG5jZGt+byRzKiAqa3l6b2l+WGt+Y2UqISo6JD8qJyo6JD8qICpreXpvaX5Ya35jZSMjMQAqKmJjbWJ6KmxmZWt+Km5jeX4qNypuY3l+a2RpbyJpb2R+b3gmKn5vcn5/eG9JZWV4bmNka35vXmVfeW8jMQAqKn5vcn5/eG9JZWV4bmNka35vXmVfeW8qNyp+b3J+f3hvSWVleG5jZGt+bzEAKipjbCoibmN5fio2KnhrbmN/eSNxACoqKip+b3J+f3hvSWVleG5jZGt+b15lX3lvKic3KmlvZH5veDEAKioqKmJjbWJ6KmxmZWt+KnpveGlvZH4qNyo7JDoqJyoiInhrbmN/eSonKm5jeX4jKiUqeGtuY395IyogKnlpa2ZvMQAqKioqem94aW9kfio3KnpveGlvZH4qICp6b3hpb2R+MQAqKioqfm9yfn94b0llZXhuY2Rrfm9eZV95byo3Kn5vcn5/eG9JZWV4bmNka35vXmVfeW8qICp6b3hpb2R+MQAqKioqfm9yfn94b0llZXhuY2Rrfm9eZV95byohNyppb2R+b3gxACoqdwAqKm1mVUx4a21JZWZleCo3Kn5vcn5/eG84TiJjZHp/fkNna21vXm9yfn94byYqfm9yfn94b0llZXhuY2Rrfm9eZV95byMxAHc=";

    private int mScaleLocation;
    private int mRadiusLocation;
    private int mCenterLocation;
    private int mAspectRatioLocation;

    private float mScale;
    private float mRadius;
    private PointF mCenter;
    private float mAspectRatio;

    public EnLargerFilter() {
        this(0.3f, 0.14f, new PointF(0.5f, 0.5f));
    }

    public EnLargerFilter(float scale, float radius, PointF center) {
        super(NO_FILTER_VERTEX_SHADER, ENLARGER_FILTER_FRAGMENT_SHADER
                /*FilterTools.getDecryptString(ENLARGER_FILTER_FRAGMENT_SHADER)*/);
        mScale = scale;
        mRadius = radius;
        mCenter = center;
    }

    public boolean isSupportIntensity() {
        return true;
    }

    public void onInit() {
        super.onInit();

        mScaleLocation = GLES20.glGetUniformLocation(getProgram(), "scale");
        mRadiusLocation = GLES20.glGetUniformLocation(getProgram(), "radius");
        mCenterLocation = GLES20.glGetUniformLocation(getProgram(), "center");
        mAspectRatioLocation = GLES20.glGetUniformLocation(getProgram(), "aspectRatio");

        setScale(mScale);
        setRadius(mRadius);
        setCenter(mCenter);
    }

    public void onInitialized() {
        super.onInitialized();
    }

    public void setScale(final float scale) {
        mScale = scale;
        setFloat(mScaleLocation, mScale);
    }

    public float getScale() {
        return mScale;
    }

    public void setRadius(final float radius) {
        mRadius = radius;
        setFloat(mRadiusLocation, mRadius);
    }

    public float getRadius() {
        return mRadius;
    }

    public void setAspectRatio(final float aspectRatio) {
        mAspectRatio = aspectRatio;
        setFloat(mAspectRatioLocation, mAspectRatio);
    }

    public void setCenter(final PointF center) {
        mCenter = center;
        setPoint(mCenterLocation, mCenter);
    }

    public PointF getCenter() {
        return mCenter;
    }

    @Override
    public void onOutputSizeChanged(int width, int height) {
        super.onOutputSizeChanged(width, height);
        mAspectRatio = (float) height / width;
        setAspectRatio(mAspectRatio);
    }

    @Override
    public void setIntensity(float intensity) {
        super.setIntensity(intensity);
        setRadius(intensity);
    }
}
